class myPromise {
    static PREDING = 'preding';
    static FULFILLED = 'fulfilled';
    static REJECTED = 'rejected';

    constructor(fn) {
        this.status = myPromise.PREDING;
        this.value = null;
        this.resolveCallbacks = [];
        this.rejectCallbacks = [];

        fn(this.resolve.bind(this), this.reject.bind(this));
    }

    resolve(value) {
        setTimeout(() => {
            if (this.status === myPromise.PREDING) {
                this.status = myPromise.FULFILLED;
                this.value = value;
                this.resolveCallbacks.forEach((callback) => {
                    callback(value);
                });
            }
        });

    };

    reject(reason) {
        setTimeout(() => {
            if (this.status === myPromise.PREDING) {
                this.status = myPromise.REJECTED;
                this.value = reason;
                this.rejectCallbacks.forEach((callback) => {
                    callback(reason);
                });
            }
        });
    }

    then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : () => { };
        onRejected = typeof onRejected === 'function' ? onRejected : () => { };
        let _this = this;
        return new myPromise((resolve, reject) => {
            if (this.status === myPromise.PREDING) {
                this.rejectCallbacks.push(onRejected);
                this.resolveCallbacks.push(onFulfilled);
            }

            if (this.status === myPromise.FULFILLED) {
                setTimeout(() => {
                    let v = _this.value ;
                    v.then( vv => {
                        resolve(vv)
                    })
                    // let x = onFulfilled(_this.value);
                    
                });
            }

            if (this.status === myPromise.REJECTED) {
                setTimeout(() => {
                    let x = onRejected(this.value);
                    reject(x);
                });
            }
        });
    }
}